﻿using System;
using System.IO;
using System.Reflection;
using net.entity.framework.common;
using net.entity.framework.query;

namespace net.entity.framework {
    public abstract class EqlEntityRef : QueryRoot {
        #region Members

        protected readonly AliasInfo aliasInfo;

        #endregion

        #region Properties

        /// <summary>
        /// Alias for current Entity table
        /// </summary>
        public AliasInfo AliasInfo {
            get { return aliasInfo; }
        }

        /// <summary>
        /// Placeholder for target EntityRef property
        /// </summary>
        internal PropertyInfo TargetProperty { get; private set; }

        public Terminal Id {
            get {
                return Terminal.Create(AliasInfo, "id", typeof (int),
                                       Utils.GetPropertyInfoFromExample(() => ((Entity) null).Id));
            }
        }

        public Terminal TypeId {
            get {
                return Terminal.Create(AliasInfo, "typeId", typeof (int),
                                       Utils.GetPropertyInfoFromExample(() => ((Entity) null).TypeId));
            }
        }

        public Terminal Revision {
            get {
                return Terminal.Create(AliasInfo, "revision", typeof (int),
                                       Utils.GetPropertyInfoFromExample(() => ((Entity) null).Revision));
            }
        }

        public EqlStar Star {
            get { return EqlStar.Create(AliasInfo); }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Used when creating from Base type
        /// </summary>
        /// <param name="aliasInfo"></param>
        protected EqlEntityRef(AliasInfo aliasInfo) {
            this.aliasInfo = aliasInfo;
            TargetProperty = null;
        }

        /// <summary>
        /// Used when creating from association
        /// </summary>
        /// <param name="aliasInfo"></param>
        /// <param name="targetProperty"></param>
        protected EqlEntityRef(AliasInfo aliasInfo, PropertyInfo targetProperty) {
            this.aliasInfo = aliasInfo;
            TargetProperty = targetProperty;
        }

        #endregion

        #region Methods

        public static EqlEntityRef GetQueryRoot(Type eqlEntityRef) {
            return null;
        }

        public override void CompileState(CompiledQueryState state) {
            state.LookupOrAddAlias(AliasInfo);
        }

        public override void EmitQuery(TextWriter writer, CompiledQueryState state) {
            var alias = state.LookupAlias(AliasInfo);
            writer.Write("{0}.[id], {0}.[typeId]", alias);
        }

        #endregion
    }
}